package logic

import (
	"context"
	"strings"

	"mall/common/modelx"
	"mall/service/backend/model"
	"mall/service/backend/rpc/internal/svc"
	"mall/service/backend/rpc/types/backend"

	"github.com/zeromicro/go-zero/core/logx"
)

type GetUserInfoLogic struct {
	ctx    context.Context
	svcCtx *svc.ServiceContext
	logx.Logger
}

func NewGetUserInfoLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserInfoLogic {
	return &GetUserInfoLogic{
		ctx:    ctx,
		svcCtx: svcCtx,
		Logger: logx.WithContext(ctx),
	}
}

func (l *GetUserInfoLogic) GetUserInfo(in *backend.UserInfoRequest) (*backend.UserInfoResponse, error) {
	userInfo, err := l.svcCtx.BackendUser.RetrieveById(l.ctx, in.UserId)
	if err != nil {
		return nil, err
	}

	var menus []*backend.MenuListItem
	var apis []string
	var currentAuthority string
	if userInfo.IsSuper > 0 {
		menuList, _, err := l.svcCtx.BackendMenu.GetList(l.ctx, model.M{
			model.BackendMenuColumns.Status: 1,
		}, -1)
		if err != nil {
			return nil, err
		}

		menus, apis = parseMenuList(menuList)
		currentAuthority = "superAdmin"
	} else {
		menuList, err := l.svcCtx.BackendUser.RetrieveMenus(l.ctx, userInfo, 1)
		if err != nil {
			return nil, err
		}

		menus, apis = parseMenuList(menuList)
		currentAuthority = "admin"
	}

	var tags []*backend.ListItem
	err = userInfo.Tags.Unmarshal(tags)
	if err != nil {
		tags = []*backend.ListItem{}
	}

	return &backend.UserInfoResponse{
		Id:               int64(userInfo.ID),
		Username:         userInfo.Username,
		Name:             userInfo.Name,
		Nickname:         userInfo.Nickname,
		Profile:          userInfo.Profile,
		Signature:        userInfo.Signature,
		Avatar:           userInfo.Avatar,
		Gender:           int32(userInfo.Gender),
		Birthday:         modelx.FormatNullDotTime(userInfo.Birthday, ""),
		Group:            userInfo.Group,
		Title:            userInfo.Title,
		Tags:             tags,
		Country:          userInfo.Country,
		Address:          userInfo.Address,
		Email:            userInfo.Email,
		Mobile:           userInfo.Mobile,
		Phone:            userInfo.Phone,
		CreatedAt:        userInfo.CreatedAt.Format("2006-01-02 15:04:05"),
		CurrentAuthority: currentAuthority,
		Menus:            menus,
		BackendApis:      apis,
	}, nil
}

func parseMenuList(list []*model.BackendMenu) (menus []*backend.MenuListItem, apis []string) {
	apiMap := make(map[string]int)
	for idx, menu := range list {
		if api := strings.TrimSpace(menu.API); len(api) > 0 {
			if _, exist := apiMap[api]; !exist {
				apis = append(apis, api)
				apiMap[api] = idx
			}
		}

		if menu.HideType > 0 {
			continue
		}

		menus = append(menus, &backend.MenuListItem{
			Id:        int64(menu.MenuID),
			ParentId:  int64(menu.ParentID),
			Name:      menu.Name,
			Slug:      menu.Slug,
			Type:      int32(menu.Type),
			Path:      menu.Path,
			Icon:      menu.Icon,
			Url:       menu.URL,
			MenuOrder: int32(menu.MenuOrder),
		})
	}

	return menus, apis
}
